import copy
import datetime
import json
from collections import deque
from dataclasses import dataclass, field
from typing import List, Literal, Optional

from typing_extensions import deprecated

from apps.task.re_pattern import RePattern

C_N_ORDER = 0  # 所有C的顺序编号


def set_c_order():
    global C_N_ORDER
    C_N_ORDER = 0


@dataclass
class Content:
    index: int = 0  # 该段落在该章节中的序号
    raw_type: str = ""  # 原始正文类型标记
    page: List[str] = field(default_factory=list)  # 正文所在页码
    text: str = ""  # 正文内容
    myparse_info: dict = field(default_factory=dict)


@dataclass
class TitleInfo:
    # work_id: str = ''  # 作品id
    chapter_sort: int = -1  # 该章节在该作品中的序号
    chapter_id: str = ''  # 章节id，work_id + '_' + chapter_sort(4位字符)
    parent_chapter_id: str = ''  # 父级章节id
    child__chapter_id: list = field(default_factory=list)  # 子集章节id
    chapter_raw_type: str = ''  # 章节原始类型标记
    # author_id: str = ''  # 作者id，可以为空
    # author: str = ''  # 作者名称
    author_info: list = field(default_factory=list)  # 作者信息
    page_info: list = field(default_factory=list)  # 页码范围，多值，数组
    page_info_all: list = field(default_factory=list)
    title: str = ''  # 标题
    volumn: str = ''  # 卷
    variant_version: str = ''  # 异文
    source: str = ''  # 出处
    content: List[Content] = field(default_factory=list)  # 正文内容，json数组


@dataclass
class DataInfo:
    _id: str = ''
    lngid: str = ''
    rawid: str = ''
    latest_date: str = ''
    source_type: int = -1
    type_id: int = -1
    process_id: str = ''
    title_info: List[TitleInfo] = field(default_factory=list)


class CInfo(object):
    """
    当出现 全角c时代表一个层级的出现，用一个CInfo记录相关信息
    """

    def __init__(self, c_num, c_index, c_chapter_sort):
        self.c_num = c_num  # c的级别数  为数字
        self.c_chapter_sort = c_chapter_sort  # C_N_ORDER的值
        self.c_index = c_index  # c的index  用于后期判断c的顺序
        self.c_page_list: List[tuple] = []  # 该c下的page (line, index)
        self.c_child: List[CInfo] = []  # c的下一级 cinfo对象 可能有多个
        self.c_parent: CInfo | None = None  # 父级别c信息，如果为c1就为空
        self.vol = ""
        self.title = ""
        self.content = []  # 正文类容
        self.source = ""  # 出处
        self.variant_version = []  # 异文
        # self.author_id = ''  # 作者id
        # self.author = ''  # 作者
        self.author_info = []

    def __repr__(self):
        return f"MyClass(c_num={self.c_num}, c_index={self.c_index}, " \
               f"c_page_list={self.c_page_list}, c_child={self.c_child},c_parent={self.c_parent}, " \
               f"vol={self.vol}, title={self.title}, content={self.content}, source={self.source}, " \
               f"variant_version={self.variant_version})"

    def add_page(self, line_tuple):
        """
        line_tuple 是 (line,index) 的元组
        添加页信息到该c类
        :param line_tuple:
        :return:
        """
        self.c_page_list.append(line_tuple)

    def get_page_info(self):
        new_page_list = copy.deepcopy(self.c_page_list)
        for item in self.content:
            new_page_list.extend(item["page"])
        for cn_info in self.c_child:
            new_page_list.extend(cn_info.get_page_info())
        return new_page_list

    def get_source(self):
        return self.source.lstrip("(").rstrip(")")


# 拆分作者为id和名字
def get_author_id(author_info):
    if '[' in author_info:
        author_id, author = author_info.split("[")
        author = author.replace("]", "")
    else:
        author_id, author = author_info, ""
    return author_id, author


class WorksOneParse(object):

    def __init__(self):
        self.data_info_dict: dict = {"author_info": []}
        self.vol: str = ""  # 卷信息
        self.top_page: List[tuple] = []  # 当没有出现c对象时记录页信息 (line, index)
        self.c1_list: List[CInfo] = []  # 所有c1对象的list
        self.latest_cinfo: CInfo | None = None  # 最后出现的cinfo对象
        # 存在 c0
        self.previous_line_c0 = False
        # 需要跳过的index
        self.skip_index = []

        # 最后出现的page
        self.latest_page = None
        # 正在处理的index 和 line
        self.now_deal_index_line = deque(maxlen=5)

        # 其他信息
        self.other_info = {}

        # Cn作者信息 取后设置为[]
        self.cn_author = []
        # 记录 作者cn属于c几，比如属于c2 记为 c2 当遇到大于等于c2的级别时销毁 cn_author
        self.cn_author_cn = []

    def parse_author(self, my_list):
        # 一般不是第一行出现作者就是第二行,其他情况为错误信息
        if RePattern.is_author_id(my_list[0]):
            author_info = my_list[0]
            list_author = author_info.split(chr(0x3000))  # 全角空格切割
            for author_info in list_author:
                author_id, author = get_author_id(author_info)
                self.data_info_dict["author_info"].append({"author_id": author_id, "author": author})
        elif RePattern.is_author_id(my_list[1]):

            author_info = my_list[1]
            list_author = author_info.split(chr(0x3000))
            for author_info in list_author:
                author_id, author = get_author_id(author_info)
                self.data_info_dict["author_info"].append({"author_id": author_id, "author": author})
        else:
            raise Exception("没有作者相关信息，错误")
        # 作者信息是全局的，赋值给全局字典
        # self.data_info_dict["author_id"] = author_id
        # self.data_info_dict["author"] = author

    # def deal_vol(self, line, my_list, index):
    #     """
    #     deprecated 废弃注解
    #     卷c0 逻辑处理
    #     :param line:
    #     :param my_list:
    #     :param index:
    #     :return:
    #     """
    #     if line[0] not in ['Ａ', 'Ｃ', '＃', 'Ｄ', 'Ｅ'] and not RePattern.is_source_tag(line):
    #         self.vol = line
    #     else:
    #         raise Exception("c0下的数据有特殊含义字符开头，错误:" + line)
    #         # 如果 这里 index+1下标超出界限也被认为是一种错误的情况
    #     if RePattern.is_page_id(my_list[index + 1]):  # 有可能出现页
    #         if not (my_list[index + 2][0] == 'Ｃ' and not RePattern.is_paragraph_tag(my_list[index + 2])):
    #             # 正常情况
    #             raise Exception("c0下第三行是页,第4行错误 : " + line)
    #         else:
    #             print("卷下面是页")
    #
    #     elif my_list[index + 1][0] == 'Ｃ' and not RePattern.is_paragraph_tag(my_list[index + 1]):
    #         # 出现这里属于正常
    #         pass
    #     else:
    #         raise Exception("c0下第三行数错误: " + line)
    #
    #     self.previous_line_c0 = False

    def cn_tag_rule(self, index, my_list, c_info, cn: str):
        """
        cn系列标签基本符合该规则
        :return:
        """
        line_count = 0
        title = ""
        title_count = 20  # title 允许行数
        while line_count < title_count:
            line_count = line_count + 1
            if index + line_count >= len(my_list):
                raise Exception(f"{cn} 下无段落类容直接结束 或者下级c标签，错误的状态")
            if line_count == 1:
                if RePattern.is_page_id(my_list[index + line_count]):
                    raise Exception(f"{cn} 下不能出现页码 ，错误的状态")
            if my_list[index + line_count][0] not in ['Ａ', 'Ｃ', '＃', 'Ｄ', 'Ｅ'] and not RePattern.is_source_tag(
                    my_list[index + line_count]) and not RePattern.is_page_id(my_list[index + line_count]):
                # 说明是标题
                title = title + my_list[index + line_count]
                self.skip_index.append(index + line_count)
                if my_list[index + line_count].startswith("("):
                    # 如果有title的注释(在古书上是小字表示),允许和标题一起不超过10行,如果遇到超过10行的后面调大这个设置
                    title_count = 30  # 当title 等于5时 设置为10，现在调大到30
            elif RePattern.is_page_id(my_list[index + line_count]):  # 如果是页
                self.latest_page = (my_list[index + line_count], index + line_count)  # 设置最后出现的页
                c_info.c_page_list.append(self.latest_page)  # 设置 c_info的页列表
                self.skip_index.append(index + line_count)  # 跳过行
            else:
                break

        if line_count >= title_count:
            raise Exception(f"title 超出设计行({title_count})上限，请确认是否有这么多行的title")

        c_info.title = title
        self.latest_cinfo = c_info

    def deal_c1(self, line, my_list, index, c_num=1):
        global C_N_ORDER
        C_N_ORDER = C_N_ORDER + 1
        c1_info = CInfo(c_num, index, C_N_ORDER)
        # c1_info.author_id = self.data_info_dict["author_id"]
        # c1_info.author = self.data_info_dict["author"]
        c1_info.author_info.extend(self.data_info_dict["author_info"])
        if self.cn_author:
            lists = [item for items in self.cn_author for item in (items if isinstance(items, list) else [items])]
            c1_info.author_info.extend(lists)
            # 去重操作
            c1_info.author_info = [dict(t) for t in {tuple(d.items()) for d in c1_info.author_info}]
        # print(f"创建 一个c1,{index}")
        if self.top_page:
            c1_info.c_page_list.extend(self.top_page)
            self.top_page.clear()
        elif self.latest_page:
            c1_info.c_page_list.append(self.latest_page)
        else:
            pass
            # 暂时认为没有page信息是正常情况
            # raise Exception("c1 没有页码信息 错误的情况")
        # 没有卷了
        # c1_info.vol = self.vol
        self.cn_tag_rule(index, my_list, c1_info, "c" + str(c_num))
        self.c1_list.append(c1_info)

    def deal_cn(self, line, my_list, index):
        num = int(line.replace("Ｃ", ""))
        # print(f"创建 一个c{num},{index}")
        if self.latest_cinfo is None:
            raise Exception("不存在上级c 层级错误")
        global C_N_ORDER
        C_N_ORDER = C_N_ORDER + 1
        cn_info = CInfo(num, index, C_N_ORDER)
        cn_info.author_info.extend(self.data_info_dict["author_info"])
        if self.cn_author:
            lists = [item for items in self.cn_author for item in (items if isinstance(items, list) else [items])]
            cn_info.author_info.extend(lists)
            # 去重操作
            cn_info.author_info = [dict(t) for t in {tuple(d.items()) for d in cn_info.author_info}]
        if self.latest_page:
            cn_info.c_page_list.append(self.latest_page)
        # else: # 按照商定 可以出现没有pege的情况
        #     raise Exception("cn  没有page信息 错误")
        if num == self.latest_cinfo.c_num + 1:  # 如果比上级小一级
            self.latest_cinfo.c_child.append(cn_info)
            cn_info.c_parent = self.latest_cinfo  # 设置父类对象
        elif num == self.latest_cinfo.c_num:  # 同级
            self.latest_cinfo.c_parent.c_child.append(cn_info)
            cn_info.c_parent = self.latest_cinfo.c_parent  # 设置父类对象
        elif num > self.latest_cinfo.c_num:  # 允许小几个级别的情况  屏蔽了 else
            # 允许c1 下面不是c2 而是更低级别的cn 这种情况
            self.latest_cinfo.c_child.append(cn_info)
            cn_info.c_parent = self.latest_cinfo  # 设置父类对象
        elif num < self.latest_cinfo.c_num:  # 如果级别比现在大
            temp_cinfo = self.latest_cinfo
            is_find = False
            for i in range(100):  # 一般不会找到这么大的步数
                temp_cinfo = temp_cinfo.c_parent
                if temp_cinfo is None:
                    raise Exception("没找到层级位置 报错")
                if num < temp_cinfo.c_num:
                    continue
                if num == temp_cinfo.c_num:
                    is_find = True
                    temp_cinfo.c_parent.c_child.append(cn_info)
                    cn_info.c_parent = temp_cinfo.c_parent  # 设置父类对象
                    break
                if num > temp_cinfo.c_num:  # 这里也是 c1下允许c3所做的兼容
                    is_find = True
                    temp_cinfo.c_child.append(cn_info)
                    cn_info.c_parent = temp_cinfo  # 设置父类对象
                    break
                    # raise Exception(f"层级错误,请检查,num {num},up_num {temp_cinfo.c_num}")
            if is_find is False:
                raise Exception("没找到对应层级,请检查")
        else:  # 允许c1 下面不是c2 而是更低级别的cn 这种情况 在前面添加了   num > self.latest_cinfo.c_num: 目前应该没有逻辑会走到这个else
            raise Exception(f"对cn的级别处理存在漏洞 num: {num},self.latest_cinfo.c_num :{self.latest_cinfo.c_num}")
        # cn_info.vol = self.vol
        self.cn_tag_rule(index, my_list, cn_info, "c" + str(num))

    def deal_paragraph(self, line, my_list, index):
        # 段落处理
        paragraph_dicts = {}
        raw_type = RePattern.get_paragraph_tag(line)
        if RePattern.is_table_start(line):  # 如果是表格 特殊处理
            if raw_type != "＃":
                raw_type = "＃"
        paragraph_dicts["raw_type"] = raw_type
        text = line.replace(raw_type, "")
        page_list = []
        if self.latest_page:
            page_list.extend([self.latest_page])
        i_count = 1
        paragraph_dicts["paragraph_index"] = index
        # 如果段落行是表开头
        table_start = False
        table_end = False
        if RePattern.is_table_start(line):
            table_start = True
        # 现在开始循环判断接下来的行
        while i_count < 2010:  # 一般不会有这么多行连续的内容
            temp_index = index + i_count
            if temp_index >= len(my_list):
                # 本文本已结束
                paragraph_dicts["text"] = text
                paragraph_dicts["page"] = page_list
                break
            temp_line = my_list[temp_index]
            i_count = i_count + 1
            if i_count >= 2000:
                raise Exception("错误，达到最大循环")
            if temp_index >= len(my_list):
                # 本文本已结束
                paragraph_dicts["text"] = text
                paragraph_dicts["page"] = page_list
                break
            elif table_start:  # 优先处理表格，因为表格有#号会引起后续判断
                if temp_line.lstrip("＃").strip()[-1] not in ["│", "┐", "┘", "┤"]:
                    raise Exception("表格行错误的结尾")
                if RePattern.is_table_middle(temp_line):
                    text = text.strip() + temp_line.lstrip("＃").strip()
                    self.skip_index.append(temp_index)  # 需要跳过这行，这行是内容
                elif RePattern.is_table_end(temp_line):
                    text = text.strip() + temp_line.lstrip("＃").strip()
                    self.skip_index.append(temp_index)  # 需要跳过这行，这行是表结尾
                    paragraph_dicts["text"] = text
                    paragraph_dicts["page"] = page_list
                    table_end = True
                    break  # 表格结束 这个段落的表格结束
                else:
                    raise Exception("表格中有其他情况,报错," + temp_line)

            elif RePattern.is_paragraph_tag(temp_line):  # 下一行是段落
                paragraph_dicts["text"] = text
                paragraph_dicts["page"] = page_list
                break

            elif RePattern.is_page_id(temp_line):  # 下一行是page
                if temp_index + 1 >= len(my_list):
                    raise Exception("page信息在一条信息的最后，前面切割错误")
                self.latest_page = (temp_line, temp_index)
                # temp_index 的下一行是 内容
                if RePattern.is_page_id(my_list[temp_index + 1]):
                    raise Exception("连续页码出现，错误")
                if my_list[temp_index + 1][0] not in ['Ａ', 'Ｃ', '＃', 'Ｄ', 'Ｅ'] and not RePattern.is_source_tag(
                        my_list[temp_index + 1]):
                    page_list.append((temp_line, temp_index))
                    self.latest_cinfo.c_page_list.append((temp_line, temp_index))
                    self.skip_index.append(temp_index)  # 需要跳过这行，这行是页
                elif my_list[temp_index + 1][0] not in ['Ａ', 'Ｃ', '＃', 'Ｄ', 'Ｅ'] and RePattern.is_source_tag(
                        my_list[temp_index + 1]):
                    """ 出现以下情况
                    䲜
                    Y00496
                    (逆怯切魚盛皃)
                    魝(語計切又吉削切說文楚人謂治魚人)
                    """

                    if temp_index + 1 < len(my_list) and \
                            (my_list[temp_index + 1][0] not in ['Ａ', 'Ｃ']):
                        page_list.append((temp_line, temp_index))
                        self.latest_cinfo.c_page_list.append((temp_line, temp_index))
                        self.skip_index.append(temp_index)  # 需要跳过这行，这行是页
                    else:
                        paragraph_dicts["text"] = text
                        paragraph_dicts["page"] = page_list
                        break
                elif RePattern.is_c1_tag(my_list[temp_index + 1]) or RePattern.is_c0_tag(
                        my_list[temp_index + 1]):
                    # 如果是c1 或者 c0 则段落结束
                    paragraph_dicts["text"] = text
                    paragraph_dicts["page"] = page_list
                    break
                elif RePattern.is_cn_tag(my_list[temp_index + 1]):
                    # 如果是 cn 就缓存起来
                    paragraph_dicts["text"] = text
                    paragraph_dicts["page"] = page_list
                    break
                else:
                    paragraph_dicts["text"] = text
                    paragraph_dicts["page"] = page_list
                    break
            elif temp_line[0] not in ['Ａ', 'Ｃ', '＃', 'Ｄ', 'Ｅ'] and not RePattern.is_source_tag(
                    temp_line):  # 下一行是文本,这个判断必须在页码判断后面
                text = text.strip() + temp_line.strip()
                self.skip_index.append(temp_index)  # 需要跳过这行，这行是内容
            elif RePattern.is_source_tag(temp_line):  # 如果是 出处格式
                # 如果下一行存在且 下一行是内容
                if temp_index + 1 < len(my_list) and \
                        (my_list[temp_index + 1][0] not in ['Ａ', 'Ｃ', '＃', 'Ｄ', 'Ｅ'] and
                         not RePattern.is_source_tag(my_list[temp_index + 1])):
                    text = text.strip() + temp_line.strip()
                    self.skip_index.append(temp_index)  # 需要跳过这行，这行是内容
                else:
                    paragraph_dicts["text"] = text
                    paragraph_dicts["page"] = page_list
                    break
            else:
                paragraph_dicts["text"] = text
                paragraph_dicts["page"] = page_list
                break
        if table_start and not table_end:
            raise Exception("表格异常结束跳出循环")
        self.latest_cinfo.content.append(paragraph_dicts)

    def deal_variant_version(self, line, my_list, index):
        variant_version = []
        i_count = 1
        # 现在开始循环判断接下来的行
        while i_count < 210:  # 一般不会有这么多行连续的内容
            temp_index = index + i_count
            if temp_index >= len(my_list):
                break
            temp_line = my_list[temp_index]

            i_count = i_count + 1
            if i_count >= 200:
                raise Exception("错误，达到最大循环")
            if temp_index >= len(my_list):
                # 本文本已结束
                break
            elif RePattern.is_paragraph_tag(temp_line):  # 下一行是段落
                break
            elif RePattern.is_page_id(temp_line):  # 下一行是page
                if temp_index + 1 < len(my_list) and my_list[temp_index + 1][0] not in ['Ａ', 'Ｃ', '＃', 'Ｄ',
                                                                                        'Ｅ'] and not RePattern.is_source_tag(
                    my_list[temp_index + 1]):
                    print(my_list[temp_index + 1])
                    # 如果页码的下一行还是正文 为异常情况
                    raise Exception("出现异文下面是页码，页码下面还是异文的情况，暂时认为这是错误数据")
                break
            elif temp_line[0] not in ['Ａ', 'Ｃ', '＃', 'Ｄ', 'Ｅ'] and not RePattern.is_source_tag(temp_line):  # 下一行是文本
                variant_version.append(temp_line)
                self.skip_index.append(temp_index)  # 需要跳过这行，这行是内容
            elif temp_line[0] in ['Ａ', 'Ｃ', '＃', 'Ｄ'] or RePattern.is_source_tag(temp_line):
                break
            else:
                raise Exception(f"异文其他情况错误:{temp_index}")
        if not self.latest_cinfo.c_num == 1:
            raise Exception("异文不属于c1,请检查")
        self.latest_cinfo.variant_version = variant_version

    def deal_index(self, index):
        """
        获取index 对应的文件和行
        :param index:
        :return:
        """
        file_num = 0
        for i, file_path in self.other_info["file_list_count"]:
            file_num = file_num + 1
            if index == 0:
                self.other_info["now_file"] = file_path
                self.other_info["now_index"] = index
                break
            if index > i:
                index = index - i
                continue
            elif index == i:
                if file_num >= self.other_info["file_count"]:
                    self.other_info["now_file"] = file_path
                    self.other_info["now_index"] = index
                    break
                else:
                    index = index - i
                    continue
            else:
                self.other_info["now_file"] = file_path
                self.other_info["now_index"] = index
                break

    def deal_c1_author(self, line):
        if self.cn_author:  # 当 cn_author 存在时 就代表该c1不是第一个c1
            if len(self.cn_author) - len(self.cn_author_cn) == 1:
                self.cn_author_cn.append(line.strip())
                # 验证逻辑
                temp_str = ""
                for i in self.cn_author_cn:
                    if temp_str < i:
                        temp_str = i
                    else:
                        raise Exception("c1:作者顺序验证错误")
            elif len(self.cn_author) - len(self.cn_author_cn) == 0:
                self.cn_author_cn = []
                self.cn_author = []
            else:
                raise Exception("c1:作者记录差距大于1,逻辑错误,检查...")

    def deal_cn_author(self, line):
        if self.cn_author:
            if len(self.cn_author) - len(self.cn_author_cn) == 1:
                self.cn_author_cn.append(line.strip())
                # 验证逻辑
                temp_str = ""
                for i in self.cn_author_cn:
                    if temp_str < i:
                        temp_str = i
                    else:
                        raise Exception("cn:作者顺序验证错误")
            elif len(self.cn_author) - len(self.cn_author_cn) == 0:
                for _ in range(len(self.cn_author_cn)):
                    if line.strip() > self.cn_author_cn[-1]:
                        # str大 等级小 比如 c3的等级 比c2小
                        break
                    else:
                        self.cn_author.pop()
                        self.cn_author_cn.pop()
            else:
                raise Exception("cn:作者记录差距大于1,逻辑错误,检查...")

    def run_parse(self, my_list: list):
        self.data_info_dict = {"author_info": []}
        # 解析全局作者信息
        self.parse_author(my_list)
        for index, line in enumerate(my_list):
            # 方便日志打印位置
            self.now_deal_index_line.append((index, line))

            # if index == 690:
            #     self.deal_index(index)
            #     if self.other_info["now_file"].find("春秋左傳.txt") > -1:
            #         print(self.other_info["now_file"])

            # 跳过某些index
            if index in self.skip_index:
                # self.skip_index.remove(index)
                # 防止 remove 只移除出现的第一个数据的情况
                self.skip_index = [x for x in self.skip_index if x != index]
                continue
            if not line:
                continue
            line = line.strip()
            # 是作者id的信息 跳过 因为parse_author以获取全局作者
            if RePattern.is_author_id(line):
                if index not in (0, 1):  # 在1和2行的作者已被处理过 不需要在这里处理
                    # 说明不是之前解析的作者
                    list_author = line.split(chr(0x3000))  # 全角空格切割
                    list_temp = []
                    for author_info in list_author:
                        author_id, author = get_author_id(author_info)
                        list_temp.append({"author_id": author_id, "author": author})
                    if not self.cn_author and not self.cn_author_cn:
                        self.cn_author.append(copy.deepcopy(list_temp))
                    elif len(self.cn_author_cn) == len(self.cn_author):
                        # 这个时候找cn的位置 找3行
                        def get_bool(line_num):
                            return line_num < len(my_list) and (
                                    RePattern.is_c1_tag(my_list[line_num]) or RePattern.is_cn_tag(my_list[line_num]))

                        def deal_cn_author(line_num):
                            for _ in range(len(self.cn_author_cn)):
                                if my_list[line_num].strip() > self.cn_author_cn[-1]:
                                    # str大 等级小 比如 c3的等级 比c2小
                                    self.cn_author.append(copy.deepcopy(list_temp))
                                    break
                                else:
                                    self.cn_author.pop()
                                    self.cn_author_cn.pop()
                            else:
                                self.cn_author.append(copy.deepcopy(list_temp))

                        if get_bool(index + 1):
                            deal_cn_author(index + 1)
                        elif get_bool(index + 2):
                            deal_cn_author(index + 2)
                        elif get_bool(index + 3):
                            deal_cn_author(index + 3)
                        else:
                            raise Exception("作者下无cn,请查看")
                    else:
                        raise Exception("处理cn作者记录错误，请检查逻辑")

            elif RePattern.is_page_id(line):  # 如果是页码信息
                # 如果是页码的行,判断现在是在CN
                self.latest_page = (line, index)
                if self.latest_cinfo is None:
                    self.top_page.append((line, index))
                else:
                    if index + 1 >= len(my_list):
                        raise Exception("page信息在一条信息的最后，前面切割错误")
                    if RePattern.is_c0_tag(my_list[index + 1]) or RePattern.is_c1_tag(my_list[index + 1]):
                        self.top_page.clear()
                        self.top_page.append((line, index))
                    else:
                        self.latest_cinfo.c_page_list.append((line, index))
            elif RePattern.is_c0_tag(line):  # 如果是 c0 当 c1, c0 和 c1 都可以是第一级
                # 记录状态 方便下次循环写入数据
                self.previous_line_c0 = True
                self.deal_c1_author(line)
                self.deal_c1(line, my_list, index, c_num=0)
            # elif self.previous_line_c0:  # 当处理c0的数据
            #     # 处理卷的相关信息
            #     self.deal_vol(line, my_list, index)
            elif RePattern.is_c1_tag(line):  # 当是c1
                if not self.previous_line_c0:  # 如果c0不存在,还是c1作为顶级
                    self.deal_c1_author(line)
                    self.deal_c1(line, my_list, index)
                else:  # 如果c0作为顶级, c1作为第二级处理
                    self.deal_c1_author(line)
                    self.deal_cn(line, my_list, index)
            elif RePattern.is_cn_tag(line):  # 当是 Cn 比如 c2 c3 c4 ...
                self.deal_cn_author(line)
                self.deal_cn(line, my_list, index)
            elif RePattern.is_paragraph_tag(line):  # 如果出现段落id
                self.deal_paragraph(line, my_list, index)
            elif RePattern.is_source_tag(line):  # 出处  source
                self.latest_cinfo.source = line
            elif line.strip() == "Ｅ":  # 异文
                self.deal_variant_version(line, my_list, index)
            else:
                raise Exception(f"没有分析到的情况:{index}:{line}")
        return self.c1_list

    def deal_c1_list(self, input_dicts):
        """
        将结构数据处理成一条一条的数据
        :return:
        """
        # 被处理的c类列表,记录这个是为了防止循环处理问题
        processed = []

        def deal_processed(cn_info):
            # 防止出现 循环依赖问题
            if id(cn_info) in processed:
                # print(processed)
                # print(cn_info)
                # print(id(cn_info))
                raise Exception("处理过这个id的c_info 可能出现循环层级依赖")
            else:
                processed.append(id(cn_info))

        def deal_cn_info(c_info_cn, num_parent, c_info_c1):
            title_info_cn = TitleInfo()
            # title_info_cn.work_id = input_dicts["work_id"]  # 这个由外围传入进来
            title_info_cn.chapter_sort = c_info_cn.c_chapter_sort
            title_info_cn.chapter_id = input_dicts["rawid"] + "_" + str(c_info_cn.c_chapter_sort).rjust(6, "0")
            if c_info_cn.c_parent:
                title_info_cn.parent_chapter_id = input_dicts["rawid"] + "_" + str(
                    c_info_cn.c_parent.c_chapter_sort).rjust(6, "0")
            else:
                title_info_cn.parent_chapter_id = ''  # 如果是c1 这里为空
            title_info_cn.child_chapter_id = [input_dicts["rawid"] + "_" + str(i.c_chapter_sort).rjust(6, "0") for i in
                                              c_info_cn.c_child]  # 子级id 列表
            title_info_cn.chapter_raw_type = 'Ｃ' + str(c_info_cn.c_num)
            # title_info_cn.author_id = c_info_cn.author_id
            # title_info_cn.author = c_info_cn.author
            title_info_cn.author_info = copy.deepcopy(c_info_cn.author_info)
            title_info_cn.title = c_info_cn.title
            # title_info_cn.volumn = c_info_c1.vol
            title_info_cn.variant_version = c_info_cn.variant_version
            title_info_cn.source = c_info_cn.get_source()
            # title_info_cn.page_info_all.extend(c_info_cn.c_page_list)  # 将c1的页码 放入 page_info_all
            title_info_cn.page_info = [item[0] for item in sorted(set(c_info_cn.c_page_list), key=lambda x: x[1])]

            if c_info_cn.content:
                sorted_data = sorted(c_info_cn.content, key=lambda x: x["paragraph_index"])
                for index, content_dicts in enumerate(sorted_data):
                    index = index + 1
                    myparse_info = json.dumps({
                        "paragraph_index": content_dicts["paragraph_index"],
                        "page": copy.deepcopy(content_dicts["page"])
                    }, ensure_ascii=False)
                    title_info_cn.page_info_all.extend(content_dicts["page"])
                    ct = Content()
                    ct.myparse_info = myparse_info
                    ct.index = index
                    ct.raw_type = content_dicts["raw_type"]
                    ct.text = content_dicts['text']
                    # 处理page问题
                    # print("***************")
                    # print(content_dicts["page"])
                    page = [item[0] for item in sorted(set(content_dicts["page"]), key=lambda x: x[1])]
                    ct.page = copy.deepcopy(page)

                    title_info_cn.content.append(ct)

            title_info_cn.page_info_all = [item[0] for item in
                                           sorted(set(c_info_cn.get_page_info()), key=lambda x: x[1])]

            return title_info_cn

        def deal_cn(c_info_cn, num_parent, c_info_c1, c1_datainfo):
            if c_info_cn.c_num <= num_parent:
                raise Exception(f"错误的层级关系,{c_info_cn.c_num}:parent is {num_parent}")
            # 避免循环依赖问题
            deal_processed(c_info_cn)
            title_info_cn = deal_cn_info(c_info_cn, num_parent, c_info_c1)  # 处理逻辑
            if title_info_cn is not False:
                c1_datainfo.title_info.append(title_info_cn)

            for c_cn in c_info_cn.c_child:
                title_info_cn = deal_cn(c_cn, c_info_cn.c_num, c_info_c1, c1_datainfo)
                if title_info_cn is not False:
                    c1_datainfo.title_info.append(title_info_cn)

            return False

        def deal_c1(c_info_c1):
            c1_datainfo = DataInfo(
                _id=input_dicts["lngid"],
                lngid=input_dicts["lngid"],
                rawid=input_dicts["rawid"],
                latest_date=input_dicts["latest_date"],
                source_type=input_dicts["source_type"],
                type_id=input_dicts["type_id"],
                process_id=input_dicts["process_id"]

            )
            deal_cn(c_info_c1, -1, c_info_c1, c1_datainfo)
            return c1_datainfo

        # print([id(c_info) for c_info in self.c1_list])
        # 处理 c1的列表 deal_c1(c_info) 是一个c1的全部信息 包括里面的cn cn在 c1 DataInfo的 title_info 列表 里面
        return [deal_c1(c_info) for c_info in self.c1_list]
